package com.example.server.config.encrypt;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.io.IOException;

/**
 * @Author: xieyonghui
 * @Date: 2019/7/3
 * @Description:
 */
@RestControllerAdvice
@ConditionalOnProperty(prefix = "faster.secret", name = "enabled", havingValue = "true")
@EnableConfigurationProperties({EncryptConfig.class})
@Order(1)
@Slf4j
public class EncryptResponseAdvice implements ResponseBodyAdvice {

    @Autowired
    private EncryptConfig encryptConfig;
    @Autowired
    private AESUtils aesUtils;


    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public boolean supports(MethodParameter methodParameter, Class aClass) {

        // 类含有注解则开启加密
        if (methodParameter.getContainingClass().getAnnotation(encryptConfig.getAnnotationClass()) != null) {
            return true;
        }
        // 方法含有注解则开启加密
        if (methodParameter.getMethodAnnotation(encryptConfig.getAnnotationClass()) != null) {
            return true;
        }
        return false;
        //return methodParameter.hasMethodAnnotation(SecretBody.class); // 只对使用该注解得方法添加加密操作
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        log.info("*****************  此处进行加密数据 *****************");
        if (null != body) {
            try {
                String encrypt = aesUtils.encrypt(objectMapper.writeValueAsString(body), encryptConfig.getDesSecretKey());
                log.info("***************** 加密数据{} *****************", encrypt);
                return encrypt;
            } catch (IOException e) {
                log.error("加密数据失败.", e);
            }
        }
        return body;
    }
}
